package com.jjb.common.ability.adapter.service;

import com.jjb.common.ability.adapter.annotate.BusinessBadgeType;
import com.jjb.common.ability.adapter.model.BusinessBadgeModel;
import com.jjb.common.ability.adapter.util.ApplicationBeanUtil;
import com.jjb.common.ability.adapter.annotate.BusinessBadgeWay;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Component
public class BusinessBadgeContentServiceImpl implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {


    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if ( this.applicationContext  == null) {
            return;
        }
        List<BusinessBadgeModel> businessBadgeModels = getBusinessBadgeModelAll();

        Map<String, IBusinessFactoryService> businessFactoryServiceMap = this.applicationContext.getBeansOfType(IBusinessFactoryService.class);
        if ( businessFactoryServiceMap != null ) {
            for ( Map.Entry<String, IBusinessFactoryService> entry: businessFactoryServiceMap.entrySet() ) {
                Object targetValue = ApplicationBeanUtil.getTarget(entry.getValue());


                if (! targetValue.getClass().isAnnotationPresent(BusinessBadgeType.class)) {
                    throw new RuntimeException("bean:\"" + entry.getKey()+"\"不存在注解:BusinessBadgeType");
                }

                BusinessBadgeType businessBadgeType = targetValue.getClass().getAnnotation(BusinessBadgeType.class);
                if( businessBadgeModels != null ) {
                    for (BusinessBadgeModel businessBadgeModel : businessBadgeModels) {
                        if ( businessBadgeModel.getBusinessType().equals(businessBadgeType.businessType()) ) {
                            entry.getValue().addBusinessService(businessBadgeModel.getBusinessWay(), businessBadgeModel.getBusinessService());
                        }
                    }
                }
            }
        }
    }

    public List<BusinessBadgeModel> getBusinessBadgeModelAll() {

        List<BusinessBadgeModel> result = new LinkedList<>();

        Map<String, IBusinessService> beanMap = this.applicationContext.getBeansOfType(IBusinessService.class);
        if( beanMap != null ) {
            for ( Map.Entry<String, IBusinessService> entry: beanMap.entrySet() ) {

                Object targetValue = ApplicationBeanUtil.getTarget(entry.getValue());
                if( ! (targetValue.getClass().isAnnotationPresent(BusinessBadgeWay.class))) {
                    throw new RuntimeException("bean:" + entry.getKey() + "未添加注解BusinessBadgeWay");
                }

                BusinessBadgeWay businessBadge = targetValue.getClass().getAnnotation(BusinessBadgeWay.class);
                BusinessBadgeModel businessBadgeModel = new BusinessBadgeModel(businessBadge.businessType(), businessBadge.businessWay());
                businessBadgeModel.setBusinessService((IBusinessService) entry.getValue());
                result.add(businessBadgeModel);
            }
        }

        return result;
    }

}
